class Door {
    public DoorState CLOSED, OPEN, OPENING, CLOSING, STAYOPEN, state;

    public Door() {
        CLOSED = new DoorClosed(this);
        OPEN = new DoorOpen(this);
        OPENING = new DoorOpening(this);
        CLOSING = new DoorClosing(this);
        STAYOPEN = new DoorStayOpen(this);
        state = CLOSED;
    }
    public void setState(DoorState state) {
        this.state = state;
    }
    public void getState() {
        state.getState();
    }
    public void click() {
        state.click();
    }
    public void complete() {
        state.complete();
    }
    public void timeout() {
        state.timeout();
    }
}
abstract class DoorState {
    protected Door door;
    public DoorState(Door door) {
        this.door = door;
    }
    public void click(){}
    public void complete(){}
    public void timeout(){}
    public abstract void getState();
}
class DoorClosed extends DoorState {
    public DoorClosed(Door door) {
        super(door);
    }
    public void click() {
        door.setState(door.OPENING);
    }
    public void getState() {
        System.out.println("DoorClosed");
    }
}
class DoorOpening extends DoorState {
    public DoorOpening(Door door) {
        super(door);
    }
    public void click() {
        door.setState(door.CLOSING);
    }
    public void complete() {
        door.setState(door.OPEN);
    }
    public void getState() {
        System.out.println("DoorOpening");
    }
}
class DoorOpen extends DoorState {
    public DoorOpen(Door door) {
        super(door);
    }
    public void click() {
        door.setState(door.STAYOPEN);
    }
    public void timeout() {
        door.setState(door.CLOSING);
    }
    public void getState() {
        System.out.println("DoorOpen");
    }
}
class DoorClosing extends DoorState {
    public DoorClosing(Door door) {
        super(door);
    }
    public void click() {
        door.setState(door.OPENING);
    }
    public void complete() {
        door.setState(door.CLOSED);
    }
    public void getState() {
        System.out.println("DoorClosing");
    }
}
class DoorStayOpen extends DoorState {
    public DoorStayOpen(Door door) {
        super(door);
    }
    public void click() {
        door.setState(door.CLOSING);
    }
    public void getState() {
        System.out.println("DoorStayOpen");
    }
}

public class Test {
    public static void main(String[] args) {
        Door door = new Door();
        door.getState();

        door.click();
        door.getState();

        door.complete();
        door.getState();

        door.timeout();
        door.getState();

        door.click();
        door.getState();

        door.complete();
        door.getState();
    }
}
